import React, { ChangeEvent, FC, useState } from "react"
import useGetComponentInfo from "../../../../hooks/useGetComponentInfo"
import { useDispatch } from "react-redux"
import styles from "./Layers.module.scss"
import classNames from "classnames"
import { Button, Input, message, Space } from "antd"
import { changeComponentHidden, changeComponentTitle, changeSelectedId, moveComponent, toggleComponentLocked } from "../../../../store/componentsReducer"
import { EyeInvisibleOutlined, LockOutlined } from "@ant-design/icons"

import SortableContainer from "../../../../components/DragSortable/SortableContainer"
import SortableItem from "../../../../components/DragSortable/SortableItem"

const Layers: FC = () => {
    const { componentList, selectedId } = useGetComponentInfo()
    const dispatch = useDispatch()

    // 记录当前正在修改标题的组件
    const [changingTitleId, setChangingTitleId] = useState("")

    function handleTitleClick(fe_id: string) {
        const currentComponent = componentList.find(c => c.fe_id === fe_id)
        if (currentComponent && currentComponent.isHidden) {
            message.info("不能选择隐藏的组件")
            return
        }
        if (fe_id !== selectedId) {
            // 当前组件未被选中，然后执行选中
            dispatch(changeSelectedId(fe_id))
            setChangingTitleId("") // 选中了，第二次再次选中才应该修改
            return
        }
        // 点击修改标题
        setChangingTitleId(fe_id)
    }

    // 修改标题
    function changeTitle(event: ChangeEvent<HTMLInputElement>) {
        const newTitle = event.target.value.trim()
        // 如果为空直接返回
        if (!newTitle) return
        // 如果没有选中也直接返回
        if (!selectedId) return

        dispatch(changeComponentTitle({ fe_id: selectedId, title: newTitle }))
    }

    // 切换隐藏、显示
    function changeHidden(fe_id: string, isHidden: boolean) {
        dispatch(changeComponentHidden({ fe_id, isHidden }))
    }

    // 切换锁定、解锁
    function changeLocked(fe_id: string) {
        dispatch(toggleComponentLocked({ fe_id }))
    }

    // SortableContainer 组件的items属性，需要每个item都有id属性
    const componentListWithId = componentList.map(c => {
        return { ...c, id: c.fe_id }
    })

    // 拖拽排序结束
    function handleDragEnd(oldIndex: number, newIndex: number) {
        // console.log("handleDragEnd", oldIndex, newIndex)
        dispatch(moveComponent({ oldIndex, newIndex }))
    }

    return (
        <div className={styles.main}>
            <SortableContainer items={componentListWithId} onDragEnd={handleDragEnd}>
                {componentList.map(c => {
                    const { fe_id, title, isHidden, isLocked } = c

                    // 拼接title className
                    const titleDefaultClassName = styles.title
                    const selectedClassName = styles.selected
                    const titleClassName = classNames({
                        // 动态属性名
                        [titleDefaultClassName]: true,
                        [selectedClassName]: fe_id === selectedId
                    })

                    return (
                        <SortableItem key={fe_id} id={fe_id}>
                            <div className={styles.wrapper}>
                                <div className={titleClassName} onClick={() => handleTitleClick(fe_id)}>
                                    {/* {title} */}
                                    {/* 如果当前选中的组件 和 正在修改组件的id相同，就显示输入框 */}
                                    {fe_id === changingTitleId && (
                                        <Input
                                            // 自动聚焦
                                            autoFocus
                                            value={title}
                                            onChange={e => changeTitle(e)}
                                            // 当按下回车时  将其设为空
                                            onPressEnter={() => setChangingTitleId("")}
                                            // 当失去焦点时  将其设为空
                                            onBlur={() => setChangingTitleId("")}
                                        />
                                    )}
                                    {/* 如果当前选中的组件 和 正在修改组建的id不相同，就显示title */}
                                    {fe_id !== changingTitleId && title}
                                </div>
                                <div className={styles.handler}>
                                    <Space>
                                        <Button
                                            className={!isHidden ? styles.btn : ""}
                                            size="small"
                                            shape="circle"
                                            icon={<EyeInvisibleOutlined />}
                                            type={isHidden ? "primary" : "text"}
                                            onClick={() => changeHidden(fe_id, !isHidden)}
                                        />
                                        <Button
                                            className={!isLocked ? styles.btn : ""}
                                            size="small"
                                            shape="circle"
                                            icon={<LockOutlined />}
                                            type={isLocked ? "primary" : "text"}
                                            onClick={() => changeLocked(fe_id)}
                                        />
                                    </Space>
                                </div>
                            </div>
                        </SortableItem>
                    )
                })}
            </SortableContainer>
        </div>
    )
}

export default Layers
